package org.fing.edu.uy.esb.adaptative.ws.utils;

import java.util.Date;

import org.fing.edu.uy.esb.adaptative.ws.egov.DelayStore;

public class WsOptionProces {

	public static void processBPS() {

		DelayStore instanciaDelay = DelayStore.getInstance();
		long amout = instanciaDelay.getBpsAmountInvoked() + 1;
		long maxAmount = instanciaDelay.getBpsMaxInvokexMin();
		

		// controlo maximo de invocaciones
		long lDateTime = new Date().getTime();
		if (instanciaDelay.getBpslastMillisecCall() == 0) {
			instanciaDelay.setBpslastMillisecCall(lDateTime);
		} else {
			long diffDateTime = lDateTime
					- instanciaDelay.getBpslastMillisecCall();
			if (diffDateTime > 60000) {
				instanciaDelay.setBpslastMillisecCall(lDateTime);
				amout = 0;
			}
		}
		
		instanciaDelay.setBpsAmountInvoked(amout);
		
		if (amout > maxAmount) {
			throw new RuntimeException("Demasiadas invocaciones");
		}

		// proceso el delay
		long delayMax = instanciaDelay.getBpsDelayMax();
		long delayMin = instanciaDelay.getBpsDelayMin();
		process(delayMax, delayMin);

		// proceso los llamados con error
		// x de cada 10 fallan en promedio.
		generarFalla(DelayStore.getInstance().getBpsFault());
	}

	public static void processDGI() {

		DelayStore instanciaDelay = DelayStore.getInstance();
		long amout = instanciaDelay.getDgiAmountInvoked() + 1;
		long maxAmount = instanciaDelay.getDgiMaxInvokexMin();
		instanciaDelay.setDgiAmountInvoked(amout);

		// proceso el delay
		long delayMax = instanciaDelay.getDgiDelayMax();
		long delayMin = instanciaDelay.getDgiDelayMin();
		process(delayMax, delayMin);

		// controlo maximo de invocaciones
		long lDateTime = new Date().getTime();
		if (instanciaDelay.getDgilastMillisecCall() == 0) {
			instanciaDelay.setDgilastMillisecCall(lDateTime);
		} else {
			long diffDateTime = lDateTime
					- instanciaDelay.getDgilastMillisecCall();
			if (diffDateTime > 60000) {
				instanciaDelay.setDgilastMillisecCall(lDateTime);
				amout = 0;
			}
		}
		instanciaDelay.setDgiAmountInvoked(amout);

		if (amout > maxAmount) {
			throw new RuntimeException("Demasiadas invocaciones");
		}

		// proceso los llamados con error
		// x de cada 10 fallan en promedio.
		generarFalla(DelayStore.getInstance().getDgiFault());
	}

	public static void processDNIC() {

		DelayStore instanciaDelay = DelayStore.getInstance();
		long amout = instanciaDelay.getDnicAmountInvoked() + 1;
		long maxAmount = instanciaDelay.getDnicMaxInvokexMin();
		// proceso el delay
		long delayMax = instanciaDelay.getDnicDelayMax();
		long delayMin = instanciaDelay.getDnicDelayMin();
		
		// controlo maximo de invocaciones
		long lDateTime = new Date().getTime();
		if (instanciaDelay.getDniclastMillisecCall() == 0) {
			instanciaDelay.setDniclastMillisecCall(lDateTime);
		} else {
			long diffDateTime = lDateTime
					- instanciaDelay.getDniclastMillisecCall();
			if (diffDateTime > 60000) {
				instanciaDelay.setDniclastMillisecCall(lDateTime);
				amout = 0;
			}
		}
		instanciaDelay.setDnicAmountInvoked(amout);
		//System.out.println(amout);

		if (amout > maxAmount) {
			process(delayMax, delayMin);
			throw new RuntimeException("Demasiadas invocaciones");
		}

		
		process(delayMax, delayMin);

		// proceso los llamados con error
		// x de cada 10 fallan en promedio.
		generarFalla(DelayStore.getInstance().getDnicFault());
	}

	private static void generarFalla(long fault) {
		long oneToTen = (long) (Math.random() * 10);
		if (fault > oneToTen) {
			throw new RuntimeException("Falla del servicio");
		}
	}

	private static long process(long delayMax, long delayMin) {

		try {
			long delay = aleatorio(delayMax, delayMin);
			Thread.sleep(delay);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return 0l;
	}

	public static long aleatorio(long max, long min) {
		return (long) (Math.random() * (max - min)) + min;
	}

}
